﻿namespace com.liyong
{
    using com.game;
    using System;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityLog;

    [RequireComponent(typeof(CommandHandler))]
    public class StateMachine : MonoBehaviour
    {
        private Dictionary<AIState.AIStateEnum, Util.VoidDelegate> callbackMap = new Dictionary<AIState.AIStateEnum, Util.VoidDelegate>();
        protected List<CommandHandler.Command> cmds = new List<CommandHandler.Command>();
        protected CommandHandler.Command lastCommand;
        public string otherState = string.Empty;
        private AIState state;
        private Dictionary<AIState.AIStateEnum, List<AIState>> stateMap = new Dictionary<AIState.AIStateEnum, List<AIState>>();
        public Vector3 targetPos = Vector3.zero;

        public void AddState(AIState state)
        {
            state.SetStateMachine(this);
            List<AIState> list = null;
            if (!this.stateMap.ContainsKey(state.type))
            {
                list = new List<AIState>();
                this.stateMap[state.type] = list;
            }
            else
            {
                list = this.stateMap[state.type];
            }
            list.Add(state);
        }

        public bool ChangeState(AIState.AIStateEnum s)
        {
            if ((this.state != null) && !this.state.CheckNextState(s))
            {
                return false;
            }
            AIState state = null;
            List<AIState> list = this.stateMap[s];
            if (list.Count <= 1)
            {
                state = list[0];
            }
            else
            {
                foreach (AIState state2 in list)
                {
                    Log.AI(base.gameObject, string.Concat(new object[] { " checkState ", state2.type.ToString(), state2.GetSubName(), " sub ", state2.CheckSubState() }));
                    if (state2.CheckSubState())
                    {
                        state = state2;
                        break;
                    }
                }
                if (state == null)
                {
                    state = list[0];
                }
            }
            if ((this.state != null) && (this.state == state))
            {
                return false;
            }
            Log.AI(base.gameObject, " newState " + state.type.ToString() + state.GetSubName());
            if (this.state != null)
            {
                Log.AI(base.gameObject, " ChangeStateFrom " + this.state.type.ToString() + this.state.GetSubName() + " to " + state.type.ToString() + state.GetSubName() + " \n " + this.lastCommand.stringCmd + " \n " + this.lastCommand.source);
                this.state.ExitState();
            }
            this.state = state;
            this.state.EnterState();
            base.StartCoroutine(this.state.RunLogic());
            return true;
        }

        public virtual bool CheckCommand()
        {
            if (this.cmds.Count > 0)
            {
                this.lastCommand = this.cmds[0];
                this.cmds.RemoveAt(0);
            }
            return false;
        }

        public Util.VoidDelegate GetCallbackAndClean(AIState.AIStateEnum type)
        {
            Util.VoidDelegate delegate2 = null;
            this.callbackMap.TryGetValue(type, out delegate2);
            this.callbackMap.Remove(type);
            return delegate2;
        }

        public AIState GetCurState()
        {
            return this.state;
        }

        public CommandHandler.Command GetLastCommand()
        {
            return this.lastCommand;
        }

        protected void OnCmd(CommandHandler.Command command)
        {
            Log.AI(base.gameObject, " stateMachine On Command ");
            if (this.cmds.Count > 10)
            {
                Log.AI(base.gameObject, " read Too Many Command in stateMachine " + this.cmds.Count);
            }
            this.cmds.Add(command);
        }

        private void OnDrawGizmos()
        {
            Gizmos.color = Color.red;
            Gizmos.DrawSphere(this.targetPos, 0.3f);
        }

        private void OnGUI()
        {
            if ((this.state != null) && Main.mainObj.TestAI)
            {
                Vector3 vector = Camera.main.WorldToScreenPoint(base.transform.position + new Vector3(0f, 0f, 0f));
                GUIStyle style = new GUIStyle {
                    fontSize = 12,
                    fontStyle = FontStyle.Normal
                };
                style.normal.textColor = new Color(1f, 1f, 1f);
                Texture2D textured = new Texture2D(1, 1);
                Color[] pixels = textured.GetPixels();
                pixels[0] = new Color(1f, 1f, 0f, 0.3f);
                textured.SetPixels(pixels);
                textured.Apply();
                style.normal.background = textured;
                if (!GUI.Button(new Rect(vector.x - 50f, Screen.height - vector.y, 140f, 50f), this.GetCurState().type.ToString() + this.GetCurState().GetSubName() + this.otherState, style))
                {
                }
            }
        }

        public void SetStateExitCallback(AIState.AIStateEnum type, Util.VoidDelegate cb)
        {
            this.callbackMap[type] = cb;
        }
    }
}

